package com.yang.demo.examples;

import com.yang.core.api.RestClient;
import com.yang.core.api.RestClientBuilder;
import com.yang.core.api.RestClientInterceptor;
import com.yang.core.model.RequestContext;
import com.yang.core.model.ResponseContext;
import com.yang.core.config.RestClientProperties;
import com.yang.core.extension.ExtensionRegistry;
import com.yang.core.interceptor.LoggingInterceptor;
import com.yang.core.plugins.auth.AuthenticationExtension;
import com.yang.core.plugins.cache.CacheExtension;
import com.yang.core.plugins.monitoring.MonitoringExtension;
import com.yang.core.plugins.retry.RetryExtension;
import lombok.extern.slf4j.Slf4j;

import java.time.Duration;
import java.util.Map;

/**
 * 高级使用示例
 * 展示可扩展性和开箱即用功能
 */
@Slf4j
public class AdvancedUsageExample {

    public static void main(String[] args) {
        System.out.println("=== RestClient 高级使用示例 ===\n");

        // 1. 开箱即用 - 零配置使用
        outOfTheBoxExample();

        // 2. Builder模式 - 流畅API
        builderApiExample();

        // 3. 扩展系统 - 自定义扩展
        extensionSystemExample();

        // 4. 预设模式 - 生产就绪配置
        presetModesExample();

        // 5. 高级配置 - 完整功能配置
        advancedConfigurationExample();

        System.out.println("\n=== 示例结束 ===");
    }

    /**
     * 1. 开箱即用示例
     */
    private static void outOfTheBoxExample() {
        System.out.println("1. 开箱即用示例");
        System.out.println("=" + "=".repeat(50));

        // 最简单的使用方式
        RestClient client = RestClient.create();

        try {
            // 发送GET请求
            var response = client.get("https://httpbin.org/get");
            System.out.println("状态码: " + response.getStatusCode());
            System.out.println("响应时间: " + response.getResponseTime() + "ms");

            // 发送POST请求
            Map<String, Object> data = Map.of("message", "Hello RestClient!");
            var postResponse = client.post("https://httpbin.org/post", data);
            System.out.println("POST请求成功: " + postResponse.isSuccess());

        } catch (Exception e) {
            System.err.println("请求失败: " + e.getMessage());
        } finally {
            client.close();
        }

        System.out.println();
    }

    /**
     * 2. Builder模式示例
     */
    private static void builderApiExample() {
        System.out.println("2. Builder模式示例");
        System.out.println("=" + "=".repeat(50));

        // 使用Builder模式创建客户端
        RestClient client = RestClient.builder()
                .baseUrl("https://httpbin.org")
                .userAgent("AdvancedRestClient/2.0")
                .defaultHeader("X-API-Version", "v1")
                .defaultHeader("X-Client-ID", "advanced-example")
                .timeout(Duration.ofSeconds(10))
                .enableRetry(true)
                .maxRetries(3)
                .retryDelay(Duration.ofMillis(500))
                .addInterceptor(new LoggingInterceptor())
                .enableCompression(true)
                .build();

        try {
            // 使用配置好的客户端
            var response = client.get("/get");
            System.out.println("Builder模式请求成功: " + response.isSuccess());

            // 检查默认请求头是否生效
            var headers = response.getHeaders();
            System.out.println("User-Agent: " + headers.get("User-Agent"));

        } catch (Exception e) {
            System.err.println("Builder模式请求失败: " + e.getMessage());
        } finally {
            client.close();
        }

        System.out.println();
    }

    /**
     * 3. 扩展系统示例
     */
    private static void extensionSystemExample() {
        System.out.println("3. 扩展系统示例");
        System.out.println("=" + "=".repeat(50));

        // 手动注册扩展
        ExtensionRegistry.register(new MonitoringExtension());
        ExtensionRegistry.register(new CacheExtension());
        ExtensionRegistry.register(new RetryExtension());

        // 创建客户端并应用扩展
        RestClient client = RestClient.builder()
                .baseUrl("https://httpbin.org")
                .applyAllExtensions()
                .build();

        try {
            // 发送请求，扩展会自动生效
            var response = client.get("/get");
            System.out.println("扩展系统请求成功: " + response.isSuccess());

            // 查看扩展统计信息
            var stats = ExtensionRegistry.getStatistics();
            System.out.println("已加载扩展数量: " + stats.get("totalExtensions"));

        } catch (Exception e) {
            System.err.println("扩展系统请求失败: " + e.getMessage());
        } finally {
            client.close();
            ExtensionRegistry.destroyAll();
        }

        System.out.println();
    }

    /**
     * 4. 预设模式示例
     */
    private static void presetModesExample() {
        System.out.println("4. 预设模式示例");
        System.out.println("=" + "=".repeat(50));

        try {
            // 开发模式 - 宽松的安全设置，详细的日志
            RestClient devClient = RestClient.builder()
                    .forDevelopment()
                    .baseUrl("https://httpbin.org")
                    .build();

            var devResponse = devClient.get("/get");
            System.out.println("开发模式请求成功: " + devResponse.isSuccess());
            devClient.close();

            // 生产模式 - 严格的安全设置，优化的性能
            RestClient prodClient = RestClient.builder()
                    .forProduction()
                    .baseUrl("https://httpbin.org")
                    .build();

            var prodResponse = prodClient.get("/get");
            System.out.println("生产模式请求成功: " + prodResponse.isSuccess());
            prodClient.close();

            // 高性能模式 - 优化的连接池和并发设置
            RestClient perfClient = RestClient.builder()
                    .forHighPerformance()
                    .baseUrl("https://httpbin.org")
                    .build();

            var perfResponse = perfClient.get("/get");
            System.out.println("高性能模式请求成功: " + perfResponse.isSuccess());
            perfClient.close();

        } catch (Exception e) {
            System.err.println("预设模式请求失败: " + e.getMessage());
        }

        System.out.println();
    }

    /**
     * 5. 高级配置示例
     */
    private static void advancedConfigurationExample() {
        System.out.println("5. 高级配置示例");
        System.out.println("=" + "=".repeat(50));

        // 创建配置属性
        RestClientProperties properties = createAdvancedProperties();

        // 基于配置属性创建扩展
        AuthenticationExtension authExt = new AuthenticationExtension(properties.getAuth());
        CacheExtension cacheExt = new CacheExtension(properties.getCache());
        MonitoringExtension monitorExt = new MonitoringExtension(properties.getMonitoring());
        RetryExtension retryExt = new RetryExtension(properties.getRetry());

        // 创建高级配置的客户端
        RestClient client = RestClient.builder()
                .baseUrl("https://httpbin.org")
                .timeout(Duration.ofSeconds(15))
                .maxConnectionsTotal(100)
                .maxConnectionsPerRoute(20)
                .enableRetry(true)
                .retryDelay(Duration.ofSeconds(1))
                .maxRetryDelay(Duration.ofSeconds(10))
                .enableCompression(true)
                .addExtensions(java.util.List.of(authExt, cacheExt, monitorExt, retryExt))
                .addInterceptor(new RestClientInterceptor() {
                    @Override
                    public void preRequest(RequestContext requestContext) {
                        // 自定义拦截器
                        System.out.println("自定义拦截器: " + requestContext.getUrl());
                    }

                    @Override
                    public void postResponse(ResponseContext responseContext) {
                        // 响应处理
                    }
                })
                .customProperty("client.name", "advanced-example")
                .customProperty("client.version", "2.0")
                .build();

        try {
            // 测试各种功能
            testAdvancedFeatures(client);

        } catch (Exception e) {
            System.err.println("高级配置请求失败: " + e.getMessage());
        } finally {
            client.close();
        }

        System.out.println();
    }

    /**
     * 创建高级配置属性
     */
    private static RestClientProperties createAdvancedProperties() {
        RestClientProperties properties = new RestClientProperties();

        // 基础配置
        properties.getBasic().setUserAgent("AdvancedRestClient/2.0");
        properties.getBasic().getDefaultHeaders().put("X-API-Version", "v2");

        // 认证配置
        properties.getAuth().setType(RestClientProperties.Auth.Type.BEARER);
        properties.getAuth().setBearerToken("your-bearer-token-here");

        // 缓存配置
        properties.getCache().setEnabled(true);
        properties.getCache().setDefaultTtl(Duration.ofMinutes(5));
        properties.getCache().setMaxEntries(1000);

        // 监控配置
        properties.getMonitoring().setEnabled(true);
        properties.getMonitoring().setLogRequests(true);
        properties.getMonitoring().setLogResponses(true);
        properties.getMonitoring().setMetricsEnabled(true);

        // 重试配置
        properties.getRetry().setEnabled(true);
        properties.getRetry().setMaxAttempts(3);
        properties.getRetry().setInitialDelay(Duration.ofMillis(1000));
        properties.getRetry().setBackoffMultiplier(2.0);

        return properties;
    }

    /**
     * 测试高级功能
     */
    private static void testAdvancedFeatures(RestClient client) {
        try {
            // 测试GET请求（会被缓存）
            System.out.println("测试缓存功能...");
            var response1 = client.get("/get");
            var response2 = client.get("/get");
            System.out.println("第一次请求时间: " + response1.getResponseTime() + "ms");
            System.out.println("第二次请求时间: " + response2.getResponseTime() + "ms (应该更快)");

            // 测试POST请求
            System.out.println("测试POST请求...");
            Map<String, Object> data = Map.of(
                "timestamp", System.currentTimeMillis(),
                "client", "advanced-example"
            );
            var postResponse = client.post("/post", data);
            System.out.println("POST请求状态: " + postResponse.getStatusCode());

            // 测试错误处理和重试
            System.out.println("测试错误处理...");
            try {
                client.get("/status/500"); // 这会触发500错误
            } catch (Exception e) {
                System.out.println("错误被正确捕获: " + e.getMessage());
            }

            // 查看客户端统计信息
            var stats = client.getStatistics();
            System.out.println("客户端统计信息: " + stats);

            // 健康检查
            boolean healthy = client.isHealthy();
            System.out.println("客户端健康状态: " + (healthy ? "健康" : "不健康"));

        } catch (Exception e) {
            System.err.println("测试高级功能失败: " + e.getMessage());
        }
    }
}